package com.example.login.service.impl;

import com.example.common.constant.MessageConstant;
import com.example.common.exception.LoginFailedException;
import com.example.login.config.JwtProperties;
import com.example.login.domain.dto.UserLoginDTO;
import com.example.login.domain.po.User;
import com.example.login.domain.vo.UserLoginVO;
import com.example.login.mapper.AuthMapper;
import com.example.login.properties.WeChatProperties;
import com.example.login.service.UserAuthService;
import com.example.login.utils.HttpUtils;
import com.example.login.utils.JwtUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class UserAuthServiceImpl implements UserAuthService {
    private final JwtProperties jwtProperties;
    private final JwtUtil jwtUtil;
    private final AuthMapper authMapper;
    private final WeChatProperties weChatProperties;
    //微信服务接口地址
    public static final String WX_LOGIN_HOST = "https://api.weixin.qq.com";
    public static final String WX_LOGIN_PATH = "/sns/jscode2session";

    @Override
    public UserLoginVO weixinLogin(UserLoginDTO userLoginDTO) throws Exception {
        String openid = getOpenid(userLoginDTO.getCode());

        // 判断openid是否为空，如果为空表示登录失败，抛出业务异常
        if (openid == null || openid.isEmpty()) {
            throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
        }

        // 判断当前用户是否为新用户
        User user = authMapper.getByOpenid(openid);

        // 如果是新用户，自动完成注册
        if (user == null) {
            user=User.builder()
                    .openid(openid)
                    .role(1)
                    .createTime(LocalDateTime.now())
                    .build();
            authMapper.insert(user);
        }
        // 登录成功 生成token
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", user.getId());
        claims.put("role", user.getRole());
        String token = jwtUtil.createJWT(jwtProperties.getSecretKey(), jwtProperties.getTtlMillis(),
                claims);
        UserLoginVO userLoginVO = UserLoginVO.builder()
                .id(user.getId())
                .openid(user.getOpenid())
                .token(token)
                .totalPoints(user.getTotalPoints())
                .nickname(user.getNickname())
                .avatar(user.getAvatar())
                .build();
        return userLoginVO;
    }

    /**
     * 获取微信openid
     * @param code
     * @return
     * @throws Exception
     */
    private String getOpenid(String code) throws Exception{
        Map<String, String> query = new HashMap<>();
        query.put("appid", weChatProperties.getAppid());
        query.put("secret", weChatProperties.getSecret());
        query.put("js_code", code);
        query.put("grant_type", "authorization_code");
        // 调用微信接口服务，获得当前微信用户的openid
        HttpResponse response = HttpUtils.doGet(WX_LOGIN_HOST, WX_LOGIN_PATH, "GET", new HashMap<>(), query);
        // 处理微信接口服务返回结果
        String responseBody = EntityUtils.toString(response.getEntity(),  "UTF-8");
        ObjectMapper mapper = new ObjectMapper();
        JsonNode rootNode = mapper.readTree(responseBody);
        String openid = rootNode.get("openid").asText();
        return openid;
    }
}
